/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.zakariya.stickyheaders;


import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import org.zakariya.stickyheaders.model.HeaderModel;
import org.zakariya.stickyheaders.model.ItemModel;

import java.util.ArrayList;
import java.util.List;

/**
 * Utils
 *
 * @since 2021-08-20
 */
public class Utils {
    private static final String TAG = "StickyHeaders";
    private static HiLogLabel sLogLabel;
    private static final int DOMAIN = 0x001;

    private Utils() {
    }

    private static HiLogLabel createLogLabel() {
        if (sLogLabel == null) {
            sLogLabel = new HiLogLabel(HiLog.LOG_APP, DOMAIN, TAG);
        }
        return sLogLabel;
    }

    /**
     * 输出info日志
     *
     * @param format  日志信息
     * @param objects 数据内容
     */
    public static void info(String format, Object... objects) {
        HiLog.info(createLogLabel(), format, objects);
    }

    /**
     * 输出debug日志
     *
     * @param format  日志信息
     * @param objects 数据内容
     */
    public static void debug(String format, Object... objects) {
        HiLog.debug(createLogLabel(), format, objects);
    }

    /**
     * 输出error日志
     *
     * @param format  日志信息
     * @param objects 数据内容
     */
    public static void error(String format, Object... objects) {
        HiLog.error(createLogLabel(), format, objects);
    }

    /**
     * 输出warn日志
     *
     * @param format  日志信息
     * @param objects 数据内容
     */
    public static void warn(String format, Object... objects) {
        HiLog.warn(createLogLabel(), format, objects);
    }

    /**
     * 输出fatal日志
     *
     * @param format  日志信息
     * @param objects 数据内容
     */
    public static void fatal(String format, Object... objects) {
        HiLog.fatal(createLogLabel(), format, objects);
    }

    /**
     * 获取demos数据源
     *
     * @return 数据集合
     */
    public static List<ItemModel> getDemosList() {
        List<ItemModel> items = new ArrayList<>();
        ItemModel itemModel = null;
        itemModel = new ItemModel("Address Book", "A simple address book demo using sections to organize people by first letter of last name", false, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("Sticky Header Callbacks", "Demonstrates use of callbacks on header positioning, allowing for elevation effects, etc", false, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("Collapsing Headers", "Demonstrates collapsing headers, where sections can be opened and closed", false, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("Stress Test", "Simple stress test of hundreds of sections, thousands of items", false, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("Sections", "Demonstrates that SectioningAdapter can be used with a vanilla RecyclerView.LinearLayoutManager", false, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("Multiple Item Types", "Demonstrates support for multiple types of item, header, &amp; footer", false, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("Paged Scrolling", "Demonstrates \"endless\" scrolling, where data can be paged in from a remote source as user scrolls", false, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("Multiple Selection", "Demonstrates selection through a contextual action bar", false, false, false, false, 0, 0);
        items.add(itemModel);
        return items;
    }

    /**
     * 获取about数据源
     *
     * @return 数据集合
     */
    public static List<ItemModel> getAboutList() {
        List<ItemModel> items = new ArrayList<>();
        ItemModel itemModel = null;
        itemModel = new ItemModel("SectioningAdapter", "SectioningAdapter is a simple RecyclerView." +
                "Adapter subclass which allows for items to be grouped into sections. " +
                "Each section may have an optional header and footer, as well as any number of items. " +
                "SectioningAdapter is designed for use with StickyHeaderLayoutManager, but works fine with a vanilla RecyclerView.LinearLayoutManager",
                true, false, false, false, 0, 0);
        items.add(itemModel);
        itemModel = new ItemModel("StickyHeaderLayoutManager", "The StickyHeaderLayoutManager is a simple RecyclerView.LayoutManager designed for use with the SectioningAdapter. " +
                "It works like an iOS UITableView where section titles are fixed to the top of the scrollview when content is scrolled up. " +
                "Its very useful for scenarios like address books.", true, false, false, false, 0, 0);
        items.add(itemModel);
        return items;
    }

    /**
     * 获取数据集合
     *
     * @param numSections        numSections
     * @param numItemsPerSection numItemsPerSection
     * @param hasFooter          hasFooter
     * @param type              type
     * @return items
     */
    public static List<ItemModel> getStickyList(int numSections, int numItemsPerSection, boolean hasFooter, int type) {
        List<ItemModel> items = new ArrayList<>();
        for (int i = 0; i < numSections; i++) {
            appendSection(i, numItemsPerSection, items, hasFooter, type);
        }
        return items;
    }

    /**
     * 数据拼接
     *
     * @param sectionIndex sectionIndex
     * @param itemCount    itemCount
     * @param items        items
     * @param hasFooter    是否有底部
     * @param type        type
     */
    private static void appendSection(int sectionIndex, int itemCount, List<ItemModel> items, boolean hasFooter, int type) {
        ItemModel itemModel = null;
        int ratio = 0;
        int count;
        if (hasFooter) {
            count = itemCount + 1;
            ratio = itemCount + 3;
        } else {
            count = itemCount;
            ratio = itemCount + 2;
        }
        int headIndex = ratio * sectionIndex;
        itemModel = new HeaderModel(sectionIndex + "", "", type, headIndex, headIndex);
        items.add(itemModel);
        for (int i = 0; i < count; i++) {
            if (i == itemCount) {
                itemModel = new ItemModel(sectionIndex + "", "End of Section ", false,
                        true, false, false, headIndex + i + 2, headIndex);
            } else {
                itemModel = new ItemModel(sectionIndex + "", "" + i, false,
                        false, false, true, headIndex + i + 2, headIndex);
            }
            items.add(itemModel);
        }
    }

    /**
     * 获取数据集合
     *
     * @param numSections        numSections
     * @param numItemsPerSection numItemsPerSection
     * @param hasFooter          hasFooter
     * @return items
     */
    public static List<ItemModel> getPagedList(int numSections, int numItemsPerSection, boolean hasFooter) {
        List<ItemModel> items = new ArrayList<>();
        for (int i = 0; i < numSections; i++) {
            appendSectionPage(i, numItemsPerSection, items, hasFooter);
        }
        return items;
    }

    /**
     * 数据拼接
     *
     * @param index     index
     * @param itemCount itemCount
     * @param items     items
     * @param hasFooter 是否有底部
     */
    private static void appendSectionPage(int index, int itemCount, List<ItemModel> items, boolean hasFooter) {
        ItemModel itemModel = null;
        itemModel = new HeaderModel("PAGE " + (index + 1), "", HeaderModel.TYPE_70vp, index * 22, index * 22);
        items.add(itemModel);
        int count;
        if (hasFooter) {
            count = itemCount + 1;
        } else {
            count = itemCount;
        }
        for (int i = 0; i < count; i++) {
            if (i == itemCount) {
                itemModel = new ItemModel("PAGE " + (index + 1), null, false, false, true, false, 0, index * 22);
            } else {
                itemModel = new ItemModel("PAGE " + (index + 1), "Item" + i, false, false, false, true, 0, index * 22);
            }
            items.add(itemModel);
        }
    }

    /**
     * 获取数据集合
     *
     * @param numSections        numSections
     * @param numItemsPerSection numItemsPerSection
     * @param hasFooter          hasFooter
     * @return items
     */
    public static List<ItemModel> getMultipleSelectionList(int numSections, int numItemsPerSection, boolean hasFooter) {
        List<ItemModel> items = new ArrayList<>();
        for (int i = 0; i < numSections; i++) {
            appendMultipleSelection(i, numItemsPerSection, items, hasFooter);
        }
        return items;
    }

    /**
     * 数据拼接
     *
     * @param index     index
     * @param itemCount itemCount
     * @param items     items
     * @param hasFooter 是否有底部
     */
    private static void appendMultipleSelection(int index, int itemCount, List<ItemModel> items, boolean hasFooter) {
        ItemModel itemModel = null;
        itemModel = new HeaderModel(index + "", "", HeaderModel.TYPE_70vp, 0, 0);
        items.add(itemModel);
        int count;
        if (hasFooter) {
            count = itemCount + 1;
        } else {
            count = itemCount;
        }
        for (int i = 0; i < count; i++) {
            if (i == itemCount) {
                itemModel = new ItemModel(index + "", "End of Section " + index,
                        false, true, true, false, 0, 0);
            } else {
                itemModel = new ItemModel(index + "", index + "/" + i, false, true, false, false, 0, 0);
            }
            items.add(itemModel);
        }
    }
}
